package com.example.mysqladmin.controller;

import com.example.mysqladmin.service.DatabaseService;
import com.example.mysqladmin.util.ExportUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/db")
@RequiredArgsConstructor
public class DatabaseController {

    private final DatabaseService databaseService;

    @GetMapping("/databases")
    public ResponseEntity<?> getAllDatabases() {
        try {
            List<String> databases = databaseService.getAllDatabases();
            System.out.println("Found databases: " + databases);
            return ResponseEntity.ok(databases);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @GetMapping("/{database}/tables")
    public ResponseEntity<?> getTables(@PathVariable String database) {
        try {
            List<String> tables = databaseService.getAllTables(database);
            System.out.println("Found tables for " + database + ": " + tables);
            return ResponseEntity.ok(tables);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @GetMapping("/{database}/{table}/structure")
    public ResponseEntity<?> getTableStructure(
            @PathVariable String database,
            @PathVariable String table) {
        try {
            List<Map<String, Object>> columns = databaseService.getTableStructure(database, table);
            return ResponseEntity.ok(columns);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", e.getMessage()));
        }
    }

    @GetMapping("/{database}/{table}/data")
    public ResponseEntity<?> getTableData(
            @PathVariable String database,
            @PathVariable String table,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            System.out.println("Requesting data for database: " + database + ", table: " + table);
            System.out.println("Page: " + page + ", Size: " + size);
            
            Map<String, Object> result = databaseService.getTableDataWithTotal(database, table, page, size);
            System.out.println("Data retrieved: " + ((List<?>) result.get("data")).size() + " rows");
            System.out.println("Total records: " + result.get("total"));
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(Collections.singletonMap("error", e.getMessage()));
        }
    }

    @PostMapping("/execute")
    public ResponseEntity<?> executeSQL(@RequestBody String sql) {
        try {
            if (sql.trim().toLowerCase().startsWith("select")) {
                return ResponseEntity.ok(databaseService.executeQuery(sql));
            } else {
                Map<String, Object> result = new HashMap<>();
                result.put("affectedRows", databaseService.executeUpdate(sql));
                return ResponseEntity.ok(result);
            }
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @GetMapping("/{database}/{table}/export/excel")
    public ResponseEntity<byte[]> exportToExcel(
            @PathVariable String database,
            @PathVariable String table) {
        try {
            List<Map<String, Object>> data = databaseService.getAllTableData(database, table);
            List<String> columns = databaseService.getTableColumns(database, table);
            
            byte[] excelBytes = ExportUtils.exportToExcel(data, columns);
            
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=" + table + ".xlsx")
                    .header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    .body(excelBytes);
        } catch (Exception e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @GetMapping("/{database}/{table}/export/sql")
    public ResponseEntity<String> exportToSql(
            @PathVariable String database,
            @PathVariable String table) {
        try {
            List<Map<String, Object>> data = databaseService.getAllTableData(database, table);
            List<String> columns = databaseService.getTableColumns(database, table);
            
            String sql = ExportUtils.generateInsertSql(table, data, columns);
            
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=" + table + ".sql")
                    .header("Content-Type", "text/plain")
                    .body(sql);
        } catch (Exception e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @PostMapping("/{database}/{table}/insert")
    public ResponseEntity<?> insertRow(
            @PathVariable String database,
            @PathVariable String table,
            @RequestBody Map<String, Object> data) {
        try {
            System.out.println("Inserting new row");
            System.out.println("Data: " + data);
            
            int id = databaseService.insertRow(database, table, data);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "新增成功");
            response.put("id", id);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            e.printStackTrace();
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(error);
        }
    }

    @PutMapping("/{database}/{table}/update/{id}")
    public ResponseEntity<?> updateRow(
            @PathVariable String database,
            @PathVariable String table,
            @PathVariable String id,
            @RequestBody Map<String, Object> data) {
        try {
            System.out.println("Updating row: " + id);
            System.out.println("Data: " + data);
            
            databaseService.updateRow(database, table, id, data);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "更新成功");
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            e.printStackTrace();
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(error);
        }
    }

    @DeleteMapping("/{database}/{table}/delete/{id}")
    public ResponseEntity<?> deleteRow(
            @PathVariable String database,
            @PathVariable String table,
            @PathVariable Object id) {
        try {
            databaseService.deleteRow(database, table, id);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @GetMapping("/{database}/{table}/row/{id}")
    public ResponseEntity<?> getRow(
            @PathVariable String database,
            @PathVariable String table,
            @PathVariable String id) {
        try {
            Map<String, Object> row = databaseService.getRow(database, table, id);
            return ResponseEntity.ok(row);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }

    @GetMapping("/{database}/{table}/export/row/{id}/excel")
    public ResponseEntity<byte[]> exportRowToExcel(
            @PathVariable String database,
            @PathVariable String table,
            @PathVariable String id) {
        try {
            Map<String, Object> row = databaseService.getRow(database, table, id);
            List<Map<String, Object>> data = Collections.singletonList(row);
            List<String> columns = new ArrayList<>(row.keySet());
            
            byte[] excelBytes = ExportUtils.exportToExcel(data, columns);
            
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=" + table + "_" + id + ".xlsx")
                    .header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    .body(excelBytes);
        } catch (Exception e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @GetMapping("/{database}/{table}/export/row/{id}/sql")
    public ResponseEntity<String> exportRowToSql(
            @PathVariable String database,
            @PathVariable String table,
            @PathVariable String id) {
        try {
            Map<String, Object> row = databaseService.getRow(database, table, id);
            List<Map<String, Object>> data = Collections.singletonList(row);
            List<String> columns = new ArrayList<>(row.keySet());
            
            String sql = ExportUtils.generateInsertSql(table, data, columns);
            
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=" + table + "_" + id + ".sql")
                    .header("Content-Type", "text/plain")
                    .body(sql);
        } catch (Exception e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @PostMapping("/executeQuery")
    public ResponseEntity<?> executeQuery(@RequestBody Map<String, String> request) {
        try {
            String sql = request.get("sql");
            List<Map<String, Object>> result = databaseService.executeQuery(sql);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(Collections.singletonMap("message", e.getMessage()));
        }
    }

    @PostMapping("/executeUpdate")
    public ResponseEntity<?> executeUpdate(@RequestBody Map<String, String> request) {
        try {
            String sql = request.get("sql");
            int affectedRows = databaseService.executeUpdate(sql);
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("affectedRows", affectedRows);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().body(Collections.singletonMap("message", e.getMessage()));
        }
    }
} 